// import com.alibaba.druid.sql.ast.*;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

// import java.io.Serializable;
// import java.util.ArrayList;
// import java.util.std::shared_ptr<std::list;

#include "SQLCaseStatement.h"
#include "../../visitor/SQLASTVisitor.h"
#include "../../../utils/listAddAll.h"
#include "../../../utils/ifeq.h"

long SQLCaseStatement_Item::serialVersionUID = 1L;

SQLCaseStatement_Item::SQLCaseStatement_Item()
{
}

SQLCaseStatement_Item::SQLCaseStatement_Item(SQLExpr_ptr conditionExpr, SQLStatement_ptr statement)
{
  setConditionExpr(conditionExpr);
  setStatement(statement);
}

SQLExpr_ptr SQLCaseStatement_Item::getConditionExpr()
{
  return this->conditionExpr;
}

void SQLCaseStatement_Item::setConditionExpr(SQLExpr_ptr conditionExpr)
{
  if (conditionExpr != nullptr)
  {
    conditionExpr->setParent(SharedObject(SQLCaseStatement_Item));
  }
  this->conditionExpr = conditionExpr;
}

SQLStatement_ptr SQLCaseStatement_Item::getStatement()
{
  return this->statement;
}

void SQLCaseStatement_Item::setStatement(SQLStatement_ptr statement)
{
  if (statement != nullptr)
  {
    statement->setParent(SharedObject(SQLCaseStatement_Item));
  }
  this->statement = statement;
}

void SQLCaseStatement_Item::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLCaseStatement_Item)))
  {
    if (this->conditionExpr != nullptr)
    {
      this->conditionExpr->accept(visitor);
    }

    if (this->statement != nullptr)
    {
      this->statement->accept(visitor);
    }
  }
  visitor->endVisit(SharedObject(SQLCaseStatement_Item));
}

//@Override
int SQLCaseStatement_Item::hashCode()
{
  int prime = 31;
  int result = 1;
  result = prime * result + ((conditionExpr == nullptr) ? 0 : conditionExpr->hashCode());
  result = prime * result + ((statement == nullptr) ? 0 : statement->hashCode());
  return result;
}

//@Override
bool SQLCaseStatement_Item::equals(Object_ptr obj)
{
  if (this == obj.get())
  {
    return true;
  }
  if (obj == nullptr)
  {
    return false;
  }
  if (getClass() != obj->getClass())
  {
    return false;
  }
  SQLCaseStatement_Item_ptr other = std::dynamic_pointer_cast<SQLCaseStatement_Item>(obj);
  if (conditionExpr == nullptr)
  {
    if (other->conditionExpr != nullptr)
    {
      return false;
    }
  }
  else if (!conditionExpr->equals(other->conditionExpr))
  {
    return false;
  }
  if (statement == nullptr)
  {
    if (other->statement != nullptr)
    {
      return false;
    }
  }
  else if (!statement->equals(other->statement))
  {
    return false;
  }
  return true;
}

SQLCaseStatement::SQLCaseStatement()
{
  SQLCaseStatement_Item_list_ptr items = std::make_shared<std::list<SQLCaseStatement_Item_ptr>>();
  SQLStatement_list_ptr elseStatements = std::make_shared<std::list<SQLStatement_ptr>>();
}

SQLExpr_ptr SQLCaseStatement::getValueExpr()
{
  return this->valueExpr;
}

void SQLCaseStatement::setValueExpr(SQLExpr_ptr valueExpr)
{
  if (valueExpr != nullptr)
  {
    valueExpr->setParent(SharedObject(SQLCaseStatement));
  }
  this->valueExpr = valueExpr;
}

SQLStatement_list_ptr SQLCaseStatement::getElseStatements()
{
  return elseStatements;
}

SQLCaseStatement_Item_list_ptr SQLCaseStatement::getItems()
{
  return this->items;
}

void SQLCaseStatement::addItem(SQLCaseStatement_Item_ptr item)
{
  if (item != nullptr)
  {
    item->setParent(SharedObject(SQLCaseStatement));
    this->items->push_back(item);
  }
}

void SQLCaseStatement::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLCaseStatement)))
  {
    if (this->valueExpr != nullptr)
    {
      this->valueExpr->accept(visitor);
    }

    if (this->items != nullptr)
    {
      for (SQLCaseStatement_Item_ptr item : *this->items)
      {
        if (item != nullptr)
        {
          item->accept(visitor);
        }
      }
    }

    if (this->elseStatements != nullptr)
    {
      for (SQLStatement_ptr item : *this->elseStatements)
      {
        if (item != nullptr)
        {
          item->accept(visitor);
        }
      }
    }
  }
  visitor->endVisit(SharedObject(SQLCaseStatement));
}

//@Override
SQLObject_list_ptr SQLCaseStatement::getChildren()
{
  SQLObject_list_ptr children = std::make_shared<std::list<SQLObject_ptr>>();
  if (valueExpr != nullptr)
  {
    children->push_back(valueExpr);
  }
  Utils::ListAddAll<SQLCaseStatement_Item, SQLObject>(this->items, children);
  Utils::ListAddAll<SQLStatement, SQLObject>(this->elseStatements, children);
  return children;
}

//@Override
bool SQLCaseStatement::equals(Object_ptr o)
{
  if (this == o.get())
  {
    return true;
  }
  if (o == nullptr || getClass() != o->getClass())
  {
    return false;
  }

  SQLCaseStatement_ptr that = std::dynamic_pointer_cast<SQLCaseStatement>(o);

  if (!IFEQ::ifeq<SQLCaseStatement_Item_ptr>(items, that->items))
  {
    return false;
  }
  if (valueExpr != nullptr ? !valueExpr->equals(that->valueExpr) : that->valueExpr != nullptr)
  {
    return false;
  }
  return elseStatements != nullptr ? IFEQ::ifeq<SQLStatement_ptr>(elseStatements, that->elseStatements) : that->elseStatements == nullptr;
}

//@Override
int SQLCaseStatement::hashCode()
{
  // int result = items->hashCode();
  int result = items->size();
  result = 31 * result + (valueExpr != nullptr ? valueExpr->hashCode() : 0);
  // result = 31 * result + (elseStatements != nullptr ? elseStatements->hashCode() : 0);
  result = 31 * result + (elseStatements != nullptr ? elseStatements->size() : 0);
  return result;
}
